home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume8 / jove / part02 < prev    next >
Encoding:
Internet Message Format  |  1987-02-02  |  59.2 KB

  1. Subject:  v08i021:  The JOVE text editor, Part02/13
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!rochester!jpayne (Jonathan Payne)
  6. Mod.sources: Volume 8, Issue 21
  7. Archive-name: jove/Part02
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If all goes well, you will see the message "End of archive 2 (of 13)."
  13. # Contents:  c.c ctype.c delete.c disp.c fmt.c re.h rec.h
  14. #   doc/cmds.doc.nr
  15. PATH=/bin:/usr/bin:/usr/ucb; export PATH
  16. echo shar: extracting "'c.c'" '(13187 characters)'
  17. if test -f 'c.c' ; then 
  18.   echo shar: will not over-write existing file "'c.c'"
  19. else
  20. sed 's/^X//' >c.c <<'@//E*O*F c.c//'
  21. X/************************************************************************
  22. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  23. X * provided to you without charge, and with no warranty.  You may give  *
  24. X * away copies of JOVE, including sources, provided that this notice is *
  25. X * included in all the files.                                           *
  26. X ************************************************************************/
  27. X
  28. X/* Contains commands for C mode.  Paren matching routines are in here. */
  29. X
  30. X#include "jove.h"
  31. X#include "re.h"
  32. X#include "ctype.h"
  33. X
  34. Xprivate
  35. Xbackslashed(lp, cpos)
  36. Xregister char    *lp;
  37. Xregister int    cpos;
  38. X{
  39. X    register int    cnt = 0;
  40. X
  41. X    while (cpos > 0 && lp[--cpos] == '\\')
  42. X        cnt++;
  43. X    return (cnt % 2);
  44. X}
  45. X
  46. Xprivate char    *p_types = "(){}[]";
  47. Xprivate int    mp_kind;
  48. X#define MP_OKAY        0
  49. X#define MP_MISMATCH    1
  50. X#define MP_UNBALANCED    2
  51. X
  52. Xmp_error()
  53. X{
  54. X    switch (mp_kind) {
  55. X    case MP_MISMATCH:
  56. X        message("[Mismatched parentheses]");
  57. X        break;
  58. X
  59. X    case MP_UNBALANCED:
  60. X        message("[Unbalanced parenthesis]");
  61. X        break;
  62. X
  63. X    case MP_OKAY:
  64. X    default:
  65. X        return;
  66. X    }
  67. X    rbell();
  68. X}
  69. X
  70. X/* Search from the current position for the paren that matches p_type.
  71. X   Search in the direction dir.  If can_mismatch is YES then it is okay
  72. X   to have mismatched parens.  If stop_early is YES then when an open
  73. X   paren is found at the beginning of a line, it is assumed that there
  74. X   is no point in backing up further.  This is so when you hit tab or
  75. X   LineFeed outside, in-between procedure/function definitions, it won't
  76. X   sit there searching all the way to the beginning of the file for a
  77. X   match that doesn't exist.  {forward,backward}-s-expression are the
  78. X   only ones that insist on getting the "true" story. */
  79. X
  80. XBufpos *
  81. Xm_paren(p_type, dir, can_mismatch, can_stop)
  82. Xchar    p_type;
  83. Xregister int    dir;
  84. X{
  85. X    static Bufpos    ret;
  86. X    Bufpos    savedot,
  87. X        *sp;
  88. X    char    re_buf[100],
  89. X        *re_alts[NALTS];
  90. X    int    count = 0;
  91. X    register char    *lp,
  92. X            c;
  93. X    char    p_match,
  94. X        re_str[128],
  95. X        *cp,
  96. X        quote_c = 0;
  97. X    register int    c_char;
  98. X    int    in_comment = NO,
  99. X        stopped = NO;
  100. X
  101. X    sprintf(re_str, "[(){}[\\]%s]", (MajorMode(CMODE)) ? "/\"'" : "\"");
  102. X    REcompile(re_str, 1, re_buf, re_alts);
  103. X    if (cp = index(p_types, p_type))
  104. X        p_match = cp[dir];
  105. X    else
  106. X        complain("[Cannot match %c's]", p_type);
  107. X    DOTsave(&savedot);
  108. X
  109. X    /* To make things a little faster I avoid copying lines into
  110. X       linebuf by setting curline and curchar by hand.  Warning:
  111. X       this is slightly to very risky.  When I did this there were
  112. X       lots of problems with procedures that expect the contents of
  113. X       curline to be in linebuf. */
  114. X    while (count >= 0) {
  115. X        sp = docompiled(dir, re_buf, re_alts);
  116. X        if (sp == 0)
  117. X            break;
  118. X        lp = lbptr(sp->p_line);
  119. X
  120. X        curline = sp->p_line;
  121. X        curchar = sp->p_char;    /* here's where I cheat */
  122. X        c_char = curchar;
  123. X        if (dir == FORWARD)
  124. X            c_char--;
  125. X
  126. X        if (backslashed(lp, c_char))
  127. X            continue;
  128. X        c = lp[c_char];
  129. X        /* check if this is a comment (if we're not inside quotes) */
  130. X        if (quote_c == 0 && c == '/') {
  131. X            if ((c_char != 0) && lp[c_char - 1] == '*')
  132. X                in_comment = (dir == FORWARD) ? NO : YES;
  133. X            else if (lp[c_char + 1] == '*')
  134. X                in_comment = (dir == FORWARD) ? YES : NO;
  135. X        }
  136. X        if (in_comment)
  137. X            continue;
  138. X        if (c == '"' || c == '\'') {
  139. X            if (quote_c == c)
  140. X                quote_c = 0;
  141. X            else if (quote_c == 0)
  142. X                quote_c = c;
  143. X        }
  144. X        if (quote_c != 0)
  145. X            continue;
  146. X        if (isopenp(c)) {
  147. X            count += dir;
  148. X            if (c_char == 0 && can_stop == YES && count >= 0) {
  149. X                stopped = YES;
  150. X                break;
  151. X            }
  152. X        } else if (isclosep(c))
  153. X            count -= dir;
  154. X    }
  155. X
  156. X    ret.p_line = curline;
  157. X    ret.p_char = curchar;
  158. X
  159. X    curline = savedot.p_line;
  160. X    curchar = savedot.p_char;    /* here's where I undo it */
  161. X
  162. X    if (count >= 0)
  163. X        mp_kind = MP_UNBALANCED;
  164. X    else if (c != p_match)
  165. X        mp_kind = MP_MISMATCH;
  166. X    else
  167. X        mp_kind = MP_OKAY;
  168. X
  169. X    /* If we stopped (which means we were allowed to stop) and there
  170. X       was an error, we clear the error so no error message is printed.
  171. X       An error should be printed ONLY when we are sure about the fact,
  172. X       namely we didn't stop prematurely HOPING that it was the right
  173. X       answer. */
  174. X    if (stopped && mp_kind != MP_OKAY) {
  175. X        mp_kind = MP_OKAY;
  176. X        return 0;
  177. X    }
  178. X    if (mp_kind == MP_OKAY || (mp_kind == MP_MISMATCH && can_mismatch == YES))
  179. X        return &ret;
  180. X    return 0;
  181. X}
  182. X
  183. Xprivate
  184. Xdo_expr(dir, skip_words)
  185. Xregister int    dir;
  186. X{
  187. X    register char    c,
  188. X            syntax = (dir == FORWARD) ? _Op : _Cl;
  189. X
  190. X    exp = 1;
  191. X    if (dir == BACKWARD)
  192. X        BackChar();
  193. X    c = linebuf[curchar];
  194. X    for (;;) {
  195. X        if (!skip_words && ismword(c)) {
  196. X            WITH_TABLE(curbuf->b_major)
  197. X            (dir == FORWARD) ? ForWord() : BackWord();
  198. X            END_TABLE();
  199. X            break;
  200. X        } else if (has_syntax(c, syntax)) {
  201. X            FindMatch(dir);
  202. X            break;
  203. X        }
  204. X        DoTimes(ForChar(), dir);
  205. X        if (eobp() || bobp())
  206. X            return;
  207. X        c = linebuf[curchar];
  208. X    }
  209. X}
  210. X
  211. XFSexpr()
  212. X{
  213. X    register int    num = exp;
  214. X
  215. X    if (exp < 0) {
  216. X        exp = -exp;
  217. X        BSexpr();
  218. X    }
  219. X    while (--num >= 0)
  220. X        do_expr(FORWARD, NO);
  221. X}
  222. X
  223. XFList()
  224. X{
  225. X    register int    num = exp;
  226. X
  227. X    if (exp < 0) {
  228. X        exp = -exp;
  229. X        BList();
  230. X    }
  231. X    while (--num >= 0)
  232. X        do_expr(FORWARD, YES);
  233. X}
  234. X
  235. XBSexpr()
  236. X{
  237. X    register int    num = exp;
  238. X
  239. X    if (exp < 0) {
  240. X        exp = -exp;
  241. X        FSexpr();
  242. X    }
  243. X    while (--num >= 0)
  244. X        do_expr(BACKWARD, NO);
  245. X}
  246. X
  247. XBList()
  248. X{
  249. X    register int    num = exp;
  250. X
  251. X    if (exp < 0) {
  252. X        exp = -exp;
  253. X        FList();
  254. X    }
  255. X    while (--num >= 0)
  256. X        do_expr(BACKWARD, YES);
  257. X}
  258. X
  259. XBUpList()
  260. X{
  261. X    Bufpos    *mp;
  262. X    char    c = (MajorMode(CMODE) ? '}' : ')');
  263. X
  264. X    mp = m_paren(c, BACKWARD, NO, YES);
  265. X    if (mp == 0)
  266. X        mp_error();
  267. X    else
  268. X        SetDot(mp);
  269. X}
  270. X
  271. XFDownList()
  272. X{
  273. X    Bufpos    *sp;
  274. X    char    *sstr = (MajorMode(CMODE) ? "[{([\\])}]" : "[()]"),
  275. X        *lp;
  276. X
  277. X    sp = dosearch(sstr, FORWARD, YES);
  278. X    if (sp != 0)
  279. X        lp = lcontents(sp->p_line);
  280. X    if (sp == 0 || has_syntax(lp[sp->p_char - 1], _Cl))
  281. X        complain("[No contained expression]");
  282. X    SetDot(sp);
  283. X}
  284. X
  285. X/* Move to the matching brace or paren depending on the current position
  286. X   in the buffer. */
  287. X
  288. Xprivate
  289. XFindMatch(dir)
  290. X{
  291. X    register Bufpos    *bp;
  292. X    register char    c = linebuf[curchar];
  293. X
  294. X    if ((index(p_types, c) == 0) ||
  295. X        (backslashed(linebuf, curchar)))
  296. X        complain((char *) 0);
  297. X    if (dir == FORWARD)
  298. X        ForChar();
  299. X    bp = m_paren(c, dir, YES, NO);
  300. X    if (dir == FORWARD)
  301. X        BackChar();
  302. X    if (bp != 0)
  303. X        SetDot(bp);
  304. X    mp_error();    /* if there is an error the user wants to
  305. X               know about it */
  306. X}
  307. X
  308. XBufpos *
  309. Xc_indent(incrmt)
  310. X{
  311. X    Bufpos    *bp;
  312. X    int    indent = 0;
  313. X
  314. X    if (bp = m_paren('}', BACKWARD, NO, YES)) {
  315. X        Bufpos    save;
  316. X
  317. X        DOTsave(&save);
  318. X        SetDot(bp);
  319. X        ToIndent();
  320. X        indent = calc_pos(linebuf, curchar);
  321. X        SetDot(&save);
  322. X    }
  323. X    if (incrmt) {
  324. X        if (indent == 0)
  325. X            incrmt = tabstop;
  326. X        else
  327. X            incrmt = (tabstop - (indent%tabstop));
  328. X    }
  329. X    n_indent(indent + incrmt);
  330. X    return bp;
  331. X}
  332. X
  333. X#ifdef CMT_FMT
  334. X
  335. Xchar    CmtFmt[80] = "/*%n%! * %c%!%n */";
  336. X
  337. XComment()
  338. X{
  339. X    FillComment(CmtFmt);
  340. X}
  341. X
  342. X/* Strip leading and trailing white space.  Skip over any imbedded '\r's. */
  343. X
  344. Xprivate
  345. Xstrip_c(from, to)
  346. Xchar    *from,
  347. X    *to;
  348. X{
  349. X    register char    *fr_p = from,
  350. X            *to_p = to,
  351. X            c;
  352. X
  353. X    while (c = *fr_p) {
  354. X        if (c == ' ' || c == '\t' || c == '\r')
  355. X            fr_p++;
  356. X        else
  357. X            break;
  358. X    }
  359. X    while (c = *fr_p) {
  360. X        if (c != '\r')
  361. X            *to_p++ = c;
  362. X        fr_p++;
  363. X    }
  364. X    while (--to_p >= to)
  365. X        if (*to_p != ' ' && *to_p != '\t')
  366. X            break;
  367. X    *++to_p = '\0';
  368. X}
  369. X
  370. Xprivate char    open_c[20],    /* the open comment format string */
  371. X        open_pat[20],    /* the search pattern for open comment */
  372. X        l_header[20],    /* the prefix for each comment line */
  373. X        l_trailer[20],    /* the suffix ... */
  374. X        close_c[20],
  375. X        close_pat[20];
  376. X
  377. Xprivate char    *comment_body[] = {
  378. X     open_c,
  379. X    l_header,
  380. X    l_trailer,
  381. X    close_c
  382. X};
  383. X                    
  384. Xprivate int    nlflags;
  385. X
  386. X/* Fill in the data structures above from the format string.  Don't return
  387. X   if there's trouble. */
  388. X
  389. Xprivate
  390. Xparse_cmt_fmt(str)
  391. Xchar    *str;
  392. X{
  393. X    register char    *fmtp = str;
  394. X    register char    **c_body = comment_body,
  395. X            *body_p = *c_body;
  396. X    int    c,
  397. X         newlines = 1;
  398. X
  399. X    /* pick apart the comment string */
  400. X    while (c = *fmtp++) {
  401. X        if (c != '%') {
  402. X            *body_p++ = c;
  403. X            continue;
  404. X        }
  405. X        switch(c = *fmtp++) {
  406. X        case 'n':
  407. X            if (newlines == 2 || newlines == 3)
  408. X                complain("%n not allowed in line header or trailer: %s",
  409. X                  fmtp - 2);
  410. X            nlflags += newlines;
  411. X            *body_p++ = '\r';
  412. X            break;
  413. X        case 't':
  414. X            *body_p++ = '\t';
  415. X            break;
  416. X        case '%':
  417. X            *body_p++ = '%';
  418. X            break;
  419. X        case '!':
  420. X        case 'c':
  421. X            newlines++;
  422. X            *body_p++ = '\0';
  423. X            body_p = *++c_body;
  424. X            break;
  425. X        default:
  426. X            complain("[Unknown comment escape: %%%c]", c);
  427. X            /* VARARGS */
  428. X            break;
  429. X        }
  430. X    }
  431. X    *body_p = '\0';
  432. X    /* make search patterns */
  433. X    strip_c(open_c, open_pat);
  434. X    strip_c(close_c, close_pat);
  435. X}
  436. X
  437. X#define NL_IN_OPEN_C  ((nlflags % 4) == 1)
  438. X#define NL_IN_CLOSE_C (nlflags >= 4)
  439. X
  440. XFillComment(format)
  441. Xchar    *format;
  442. X{
  443. X    int    saveRMargin,
  444. X        indent_pos,
  445. X        close_at_dot = 0,
  446. X        slen,
  447. X        header_len,
  448. X        trailer_len;
  449. X    register char    *cp;
  450. X    static char    inside_err[] = "[Must be between %s and %s to re-format]";
  451. X    Bufpos    open_c_pt,
  452. X        close_c_pt,
  453. X        tmp_bp,
  454. X        *match_o,
  455. X        *match_c;
  456. X    Mark    *entry_mark,
  457. X        *open_c_mark,
  458. X        *savedot;
  459. X
  460. X    parse_cmt_fmt(format);
  461. X    /* figure out if we're "inside" a comment */
  462. X     if ((match_o = dosearch(open_pat, BACKWARD, 0)) == 0)
  463. X        /* VARARGS */
  464. X        complain("No opening %s to match to.", open_pat);
  465. X    open_c_pt = *match_o;
  466. X    if ((match_c = dosearch(close_pat, BACKWARD, NO)) != 0 &&
  467. X        inorder(open_c_pt.p_line, open_c_pt.p_char,
  468. X            match_c->p_line, match_c->p_char))
  469. X          complain(inside_err, open_pat, close_pat);
  470. X    if ((match_o = dosearch(open_pat, FORWARD, NO)) != 0) {
  471. X        tmp_bp = *match_o;
  472. X        match_o = &tmp_bp;
  473. X    } 
  474. X    if ((match_c = dosearch(close_pat, FORWARD, 0)) != (Bufpos *) 0)
  475. X        close_c_pt = *match_c;
  476. X
  477. X    /* Here's where we figure out whether to format from dot or from
  478. X       the close comment.  Note that we've already searched backwards to
  479. X       find the open comment symbol for the comment we are formatting.
  480. X       The open symbol mentioned below refers to the possible existence
  481. X       of the next comment.  There are 5 cases:
  482. X        1) no open or close symbol        ==> dot
  483. X        2) open, but no close symbol        ==> dot
  484. X        3) close, but no open            ==> close
  485. X        4) open, close are inorder        ==> dot
  486. X        5) open, close are not inorder        ==> close */
  487. X
  488. X
  489. X    if (match_o == (Bufpos *) 0) {
  490. X        if (match_c == (Bufpos *) 0)
  491. X            close_at_dot++;
  492. X    } else if (match_c == (Bufpos *) 0)
  493. X        close_at_dot++;
  494. X    else if (inorder(match_o->p_line, match_o->p_char,
  495. X         match_c->p_line, match_c->p_char))
  496. X        close_at_dot++;
  497. X
  498. X    if (close_at_dot) {
  499. X        close_c_pt.p_line = curline;
  500. X        close_c_pt.p_char = curchar;
  501. X    } else {
  502. X        SetDot(match_c);
  503. X    }
  504. X    SetDot(&open_c_pt);
  505. X    open_c_mark = MakeMark(curline, curchar, FLOATER);
  506. X    indent_pos = calc_pos(linebuf, curchar);
  507. X    /* search for a close comment; delete it if it exits */
  508. X    SetDot(&close_c_pt);
  509. X    if (close_at_dot == 0) {
  510. X        slen = strlen(close_pat);
  511. X        while (slen--)
  512. X            DelPChar();
  513. X    }
  514. X    entry_mark = MakeMark(curline, curchar, FLOATER);
  515. X    ToMark(open_c_mark);
  516. X    /* always separate the comment body from anything preceeding it */
  517. X    LineInsert(1);
  518. X    DelWtSpace();
  519. X    Bol();
  520. X    for (cp = open_c; *cp; cp++) {
  521. X        if (*cp == '\r') {
  522. X            if (!eolp())
  523. X                LineInsert(1);
  524. X            else
  525. X                line_move(FORWARD, NO);
  526. X        } else if (*cp == ' ' || *cp == '\t') {
  527. X            if (linebuf[curchar] != *cp)
  528. X                Insert(*cp);
  529. X        } else
  530. X            /* Since we matched the open comment string on this
  531. X               line, we don't need to worry about crossing line
  532. X               boundaries. */
  533. X            curchar++;
  534. X    }
  535. X    savedot = MakeMark(curline, curchar, FLOATER);
  536. X
  537. X    /* We need to strip the line header pattern of leading white space
  538. X       since we need to match the line after all of its leading
  539. X       whitespace is gone. */
  540. X    for (cp = l_header; *cp && (isspace(*cp)); cp++)
  541. X        ;
  542. X    header_len = strlen(cp);
  543. X    trailer_len = strlen(l_trailer);
  544. X
  545. X    /* Strip each comment line of the open and close comment strings
  546. X       before reformatting it. */
  547. X
  548. X    do {
  549. X        Bol();
  550. X        DelWtSpace();
  551. X        if (header_len && !strncmp(linebuf, cp, header_len))
  552. X            DoTimes(DelNChar(), header_len);
  553. X        if (trailer_len) {
  554. X            Eol();
  555. X            if ((curchar > trailer_len) &&
  556. X                (!strncmp(&linebuf[curchar - trailer_len],
  557. X                      l_trailer, trailer_len)))
  558. X                DoTimes(DelPChar(), trailer_len);
  559. X        }
  560. X        if (curline->l_next != 0)
  561. X            line_move(FORWARD, NO);
  562. X        else
  563. X            break;
  564. X    } while (curline != entry_mark->m_line->l_next);
  565. X
  566. X    DoSetMark(savedot->m_line, savedot->m_char);
  567. X    ToMark(entry_mark);
  568. X    saveRMargin = RMargin;
  569. X    RMargin = saveRMargin - strlen(l_header) -
  570. X          strlen(l_trailer) - indent_pos + 2;
  571. X    /* do not use the left margin */
  572. X    exp_p = NO;
  573. X    do_rfill();
  574. X    RMargin = saveRMargin;
  575. X    /* get back to the start of the comment */
  576. X    PopMark(); 
  577. X    do {
  578. X        if (curline == open_c_mark->m_line->l_next) {
  579. X            ;
  580. X        } else {
  581. X            n_indent(indent_pos);
  582. X            ins_str(l_header, NO);
  583. X        }
  584. X        Eol();
  585. X        if (!NL_IN_CLOSE_C && (curline == entry_mark->m_line))
  586. X            ;
  587. X        else
  588. X            ins_str(l_trailer, NO);
  589. X        if (curline->l_next != 0)
  590. X            line_move(FORWARD, NO);
  591. X        else 
  592. X            break;
  593. X    } while (curline != entry_mark->m_line->l_next);
  594. X    /* handle the close comment symbol */
  595. X    if (curline == entry_mark->m_line->l_next) {
  596. X        line_move(BACKWARD, NO);
  597. X        Eol();
  598. X    }
  599. X    DelWtSpace();
  600. X    /* if the addition of the close symbol would cause the line to be
  601. X       too long, put the close symbol on the next line. */
  602. X    if (strlen(close_c) + calc_pos(linebuf, curchar) > RMargin) {
  603. X        LineInsert(1);
  604. X        n_indent(indent_pos);
  605. X    }
  606. X    for (cp = close_c; *cp; cp++) {
  607. X        if (*cp == '\r') {
  608. X            LineInsert(1);
  609. X            n_indent(indent_pos);
  610. X        } else
  611. X            Insert(*cp);
  612. X    }
  613. X    ToMark(open_c_mark);
  614. X    Eol();
  615. X    exp_p = NO;
  616. X    DelNChar();
  617. X}
  618. X
  619. X#endif CMT_FMT
  620. X
  621. @//E*O*F c.c//
  622. if test 13187 -ne "`wc -c <'c.c'`"; then
  623.     echo shar: error transmitting "'c.c'" '(should have been 13187 characters)'
  624. fi
  625. fi # end of overwriting check
  626. echo shar: extracting "'ctype.c'" '(3709 characters)'
  627. if test -f 'ctype.c' ; then 
  628.   echo shar: will not over-write existing file "'ctype.c'"
  629. else
  630. sed 's/^X//' >ctype.c <<'@//E*O*F ctype.c//'
  631. X/************************************************************************
  632. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  633. X * provided to you without charge, and with no warranty.  You may give  *
  634. X * away copies of JOVE, including sources, provided that this notice is *
  635. X * included in all the files.                                           *
  636. X ************************************************************************/
  637. X
  638. X#include "jove.h"
  639. X#include "ctype.h"
  640. X
  641. Xint    SyntaxTable = FUNDAMENTAL;    /* Current table to use. */
  642. X
  643. Xchar CharTable[NMAJORS][128] = {
  644. X{    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  645. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  646. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  647. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  648. X    _P,    _P,    _P,    _P,    _P,    _P,    _P,    _P,
  649. X    _Op|_P,    _Cl|_P,    _P,    _P,    _P,    _P,    _P,    _P,
  650. X    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,
  651. X    _W|_N,    _W|_N,    _P,    _P,    _P,    _P,    _P,    _P,
  652. X    _P,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  653. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  654. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  655. X    _W|_U,    _W|_U,    _W|_U,    _Op|_P,    _P,    _Cl|_P,    _P,    _P,
  656. X    _P,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  657. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  658. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  659. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C    },
  660. X
  661. X{    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  662. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  663. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  664. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  665. X    _P,    _P,    _P,    _P,    _P,    _P,    _P,    _P|_W,
  666. X    _Op|_P,    _Cl|_P,    _P,    _P,    _P,    _P,    _P,    _P,
  667. X    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,
  668. X    _W|_N,    _W|_N,    _P,    _P,    _P,    _P,    _P,    _P,
  669. X    _P,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  670. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  671. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  672. X    _W|_U,    _W|_U,    _W|_U,    _Op|_P,    _P,    _Cl|_P,    _P,    _P,
  673. X    _P,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  674. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  675. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  676. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C    },
  677. X
  678. X{    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  679. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  680. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  681. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  682. X    _P,    _P,    _P,    _P,    _P|_W,    _P,    _P,    _P,
  683. X    _Op|_P,    _Cl|_P,    _P,    _P,    _P,    _P,    _P,    _P,
  684. X    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,
  685. X    _W|_N,    _W|_N,    _P,    _P,    _P,    _P,    _P,    _P,
  686. X    _P,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  687. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  688. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  689. X    _W|_U,    _W|_U,    _W|_U,    _Op|_P,    _P,    _Cl|_P,    _P,    _P|_W,
  690. X    _P,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  691. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  692. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  693. X    _W|_L,    _W|_L,    _W|_L,    _Op|_P,    _P,    _Cl|_P,    _P,    _C    
  694. X#ifndef LISP
  695. X}
  696. X#else
  697. X},
  698. X
  699. X{    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  700. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  701. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  702. X    _C,    _C,    _C,    _C,    _C,    _C,    _C,    _C,
  703. X    _P,    _W|_P,    _P,    _P,    _W|_P,    _W|_P,    _W|_P,    _P,
  704. X    _Op|_P,    _Cl|_P,    _W|_P,    _W|_P,    _P,    _W|_P,    _P,    _P,
  705. X    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,    _W|_N,
  706. X    _W|_N,    _W|_N,    _W|_P,    _P,    _W|_P,    _W|_P,    _W|_P,    _W|_P,
  707. X    _W|_P,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  708. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  709. X    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,    _W|_U,
  710. X    _W|_U,    _W|_U,    _W|_U,    _Op|_P,    _P,    _Cl|_P,    _W|_P,    _W|_P,
  711. X    _P,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  712. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  713. X    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,    _W|_L,
  714. X    _W|_L,    _W|_L,    _W|_L,    _Op|_W|_P,    _W|_P,    _Cl|_W|_P,    _W|_P,    _W|_C    },
  715. X#endif
  716. X};
  717. X
  718. Xismword(c)
  719. X{
  720. X    return ((CharTable[curbuf->b_major])[c]&(_W));
  721. X}
  722. @//E*O*F ctype.c//
  723. if test 3709 -ne "`wc -c <'ctype.c'`"; then
  724.     echo shar: error transmitting "'ctype.c'" '(should have been 3709 characters)'
  725. fi
  726. fi # end of overwriting check
  727. echo shar: extracting "'delete.c'" '(6395 characters)'
  728. if test -f 'delete.c' ; then 
  729.   echo shar: will not over-write existing file "'delete.c'"
  730. else
  731. sed 's/^X//' >delete.c <<'@//E*O*F delete.c//'
  732. X/************************************************************************
  733. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  734. X * provided to you without charge, and with no warranty.  You may give  *
  735. X * away copies of JOVE, including sources, provided that this notice is *
  736. X * included in all the files.                                           *
  737. X ************************************************************************/
  738. X
  739. X/* Routines to perform all kinds of deletion.  */
  740. X
  741. X#include "jove.h"
  742. X
  743. X/* Assumes that either line1 or line2 is actual the current line, so it can
  744. X   put its result into linebuf. */
  745. X
  746. Xpatchup(line1, char1, line2, char2)
  747. XLine    *line1,
  748. X    *line2;
  749. Xregister int    char1,
  750. X        char2;
  751. X{
  752. X    if (line1 != line2)
  753. X        ChkWindows(line1, line2);
  754. X    DotTo(line1, char1);
  755. X    modify();
  756. X    linecopy(linebuf, curchar, lcontents(line2) + char2);
  757. X
  758. X    /* The following is a redisplay optimization. */
  759. X    if (line1 != line2 && (char1 == 0 && char2 == 0))
  760. X        line1->l_dline = line2->l_dline;
  761. X
  762. X    DFixMarks(line1, char1, line2, char2);
  763. X    makedirty(curline);
  764. X}
  765. X
  766. X/* Deletes the region by unlinking the lines in the middle,
  767. X   and patching things up.  The unlinked lines are still in
  768. X   order.  */
  769. X
  770. XLine *
  771. Xreg_delete(line1, char1, line2, char2)
  772. XLine    *line1,
  773. X    *line2;
  774. X{
  775. X    register Line    *retline;
  776. X
  777. X    if ((line1 == line2 && char1 == char2) || line2 == 0)
  778. X        complain((char *) 0);
  779. X    (void) fixorder(&line1, &char1, &line2, &char2);
  780. X
  781. X    retline = nbufline();    /* New buffer line */
  782. X
  783. X    (void) ltobuf(line1, genbuf);
  784. X    if (line1 == line2)
  785. X        genbuf[char2] = '\0';
  786. X
  787. X    retline->l_prev = 0;
  788. X    retline->l_dline = putline(&genbuf[char1]);
  789. X    patchup(line1, char1, line2, char2);
  790. X
  791. X    if (line1 == line2)
  792. X        retline->l_next = 0;
  793. X    else {
  794. X        retline->l_next = line1->l_next;
  795. X        (void) ltobuf(line2, genbuf);
  796. X        genbuf[char2] = '\0';
  797. X        line2->l_dline = putline(genbuf);
  798. X        /* Shorten this line */
  799. X    }
  800. X
  801. X    if (line1 != line2) {
  802. X        line1->l_next = line2->l_next;
  803. X        if (line1->l_next)
  804. X            line1->l_next->l_prev = line1;
  805. X        else
  806. X            curbuf->b_last = line1;
  807. X        line2->l_next = 0;
  808. X    }
  809. X
  810. X    return retline;
  811. X}
  812. X
  813. Xlremove(line1, line2)
  814. Xregister Line    *line1,
  815. X        *line2;
  816. X{
  817. X    Line    *next = line1->l_next;
  818. X
  819. X    if (line1 == line2)
  820. X        return;
  821. X    line1->l_next = line2->l_next;
  822. X    if (line1->l_next)
  823. X        line1->l_next->l_prev = line1;
  824. X    else
  825. X        curbuf->b_last = line1;
  826. X    lfreereg(next, line2);    /* Put region at end of free line list. */
  827. X}
  828. X
  829. X/* Delete character forward */
  830. X
  831. XDelNChar()
  832. X{
  833. X    del_char(1);
  834. X}
  835. X
  836. X/* Delete character backward */
  837. X
  838. XDelPChar()
  839. X{
  840. X    if (MinorMode(OverWrite)) {
  841. X        int    count = min(exp, curchar);
  842. X
  843. X        DoTimes(BackChar(), count);
  844. X        LastKeyStruck = ' ';    /* can you say gross? */
  845. X        DoTimes(SelfInsert(), count);
  846. X        DoTimes(BackChar(), count);
  847. X    } else        
  848. X        del_char(0);
  849. X}
  850. X
  851. X/* Delete some characters.  If deleting `forward' then call for_char
  852. X   to the final position otherwise call back_char.  Then delete the
  853. X   region between the two with patchup(). */
  854. X
  855. Xdel_char(forward)
  856. X{
  857. X    Bufpos    before,
  858. X        after;
  859. X    int    killp = (exp_p && abs(exp) > 1);
  860. X
  861. X    DOTsave(&before);
  862. X    (forward) ? ForChar() : BackChar();
  863. X    if (before.p_line == curline && before.p_char == curchar)
  864. X        complain((char *) 0);
  865. X    if (killp)
  866. X        reg_kill(before.p_line, before.p_char, 1);
  867. X    else {
  868. X        DOTsave(&after);
  869. X        (void) fixorder(&before.p_line, &before.p_char, &after.p_line, &after.p_char);
  870. X        patchup(before.p_line, before.p_char, after.p_line, after.p_char);
  871. X        lremove(before.p_line, after.p_line);
  872. X    }
  873. X}
  874. X
  875. X/* This kills a region between point, and line1/char1 and puts it on
  876. X   the kill-ring.  If the last command was one of the kill commands,
  877. X   the region is appended (prepended if backwards) to the last entry.  */
  878. X
  879. Xint    killptr = 0;
  880. XLine    *killbuf[NUMKILLS];
  881. X
  882. Xreg_kill(line2, char2, dot_moved)
  883. XLine    *line2;
  884. X{
  885. X    Line    *nl,
  886. X        *line1 = curline;
  887. X    int    char1 = curchar;
  888. X    int    backwards;
  889. X
  890. X    backwards = !fixorder(&line1, &char1, &line2, &char2);
  891. X    /* This is a kludge!  But it possible for commands that don't
  892. X       know which direction they are deleting in (e.g., delete
  893. X       previous word could have been called with a negative argument
  894. X       in which case, it wouldn't know that it really deleted
  895. X       forward. */
  896. X
  897. X    if (!dot_moved)
  898. X        backwards = !backwards;
  899. X
  900. X    DotTo(line1, char1);
  901. X
  902. X    nl = reg_delete(line1, char1, line2, char2);
  903. X
  904. X    if (last_cmd != KILLCMD) {
  905. X        killptr = ((killptr + 1) % NUMKILLS);
  906. X        lfreelist(killbuf[killptr]);
  907. X        killbuf[killptr] = nl;
  908. X    } else {
  909. X        Line    *lastln = lastline(nl);
  910. X
  911. X        if (backwards)
  912. X            (void) DoYank(nl, 0, lastln, length(lastln), killbuf[killptr], 0, (Buffer *) 0);
  913. X        else {
  914. X            Line    *olastln = lastline(killbuf[killptr]);
  915. X
  916. X            (void) DoYank(nl, 0, lastln, length(lastln), olastln, length(olastln), (Buffer *) 0);
  917. X        }
  918. X    }
  919. X    this_cmd = KILLCMD;
  920. X}
  921. X
  922. XDelReg()
  923. X{
  924. X    register Mark    *mp = CurMark();
  925. X
  926. X    reg_kill(mp->m_line, mp->m_char, 0);
  927. X}
  928. X
  929. X/* Save a region.  A pretend kill. */
  930. X
  931. XCopyRegion()
  932. X{
  933. X    register Line    *nl;
  934. X    register Mark    *mp;
  935. X    register int    status;
  936. X
  937. X    mp = CurMark();
  938. X    if (mp->m_line == curline && mp->m_char == curchar)
  939. X        complain((char *) 0);
  940. X
  941. X    killptr = ((killptr + 1) % NUMKILLS);
  942. X    if (killbuf[killptr])
  943. X        lfreelist(killbuf[killptr]);
  944. X    nl = killbuf[killptr] = nbufline();
  945. X    SavLine(nl, NullStr);
  946. X    nl->l_next = nl->l_prev = 0;
  947. X
  948. X    status = inorder(mp->m_line, mp->m_char, curline, curchar);
  949. X    if (status == -1)
  950. X        return;
  951. X
  952. X    if (status)
  953. X        (void) DoYank(mp->m_line, mp->m_char, curline, curchar,
  954. X                nl, 0, (Buffer *) 0);
  955. X    else
  956. X        (void) DoYank(curline, curchar, mp->m_line, mp->m_char,
  957. X                nl, 0, (Buffer *) 0);
  958. X}
  959. X
  960. XDelWtSpace()
  961. X{
  962. X    register char    *ep = &linebuf[curchar],
  963. X            *sp = &linebuf[curchar];
  964. X
  965. X    while (*ep == ' ' || *ep == '\t')
  966. X        ep++;
  967. X    while (sp > linebuf && *(sp - 1) == ' ' || *(sp - 1) == '\t')
  968. X        sp--;
  969. X    if (sp != ep) {
  970. X        curchar = sp - linebuf;
  971. X        DFixMarks(curline, curchar, curline, curchar + (ep - sp));
  972. X        strcpy(sp, ep);
  973. X        makedirty(curline);
  974. X        modify();
  975. X    }
  976. X}
  977. X
  978. XDelBlnkLines()
  979. X{
  980. X    register Mark    *dot;
  981. X    int    all;
  982. X
  983. X    exp = 1;
  984. X    if (!blnkp(&linebuf[curchar]))
  985. X        return;
  986. X    dot = MakeMark(curline, curchar, FLOATER);
  987. X    all = !blnkp(linebuf);
  988. X    while (blnkp(linebuf) && curline->l_prev)
  989. X        SetLine(curline->l_prev);
  990. X    all |= (firstp(curline));
  991. X    Eol();
  992. X    DelWtSpace();
  993. X    line_move(FORWARD, NO);
  994. X    while (blnkp(linebuf) && !eobp()) {
  995. X        DelWtSpace();
  996. X        DelNChar();
  997. X    }
  998. X    if (!all && !eobp())
  999. X        OpenLine();
  1000. X    ToMark(dot);
  1001. X    DelMark(dot);
  1002. X}
  1003. X
  1004. XDelNWord()
  1005. X{
  1006. X    dword(1);
  1007. X}
  1008. X
  1009. XDelPWord()
  1010. X{
  1011. X    dword(0);
  1012. X}
  1013. X
  1014. Xdword(forward)
  1015. X{
  1016. X    Bufpos    savedot;
  1017. X
  1018. X    DOTsave(&savedot);
  1019. X    forward ? ForWord() : BackWord();
  1020. X    reg_kill(savedot.p_line, savedot.p_char, 1);
  1021. X}
  1022. @//E*O*F delete.c//
  1023. if test 6395 -ne "`wc -c <'delete.c'`"; then
  1024.     echo shar: error transmitting "'delete.c'" '(should have been 6395 characters)'
  1025. fi
  1026. fi # end of overwriting check
  1027. echo shar: extracting "'disp.c'" '(24166 characters)'
  1028. if test -f 'disp.c' ; then 
  1029.   echo shar: will not over-write existing file "'disp.c'"
  1030. else
  1031. sed 's/^X//' >disp.c <<'@//E*O*F disp.c//'
  1032. X/************************************************************************
  1033. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  1034. X * provided to you without charge, and with no warranty.  You may give  *
  1035. X * away copies of JOVE, including sources, provided that this notice is *
  1036. X * included in all the files.                                           *
  1037. X ************************************************************************/
  1038. X
  1039. X#include "jove.h"
  1040. X#include "ctype.h"
  1041. X#include "termcap.h"
  1042. X
  1043. X#include <varargs.h>
  1044. X#include <signal.h>
  1045. X#include <sys/stat.h>
  1046. X
  1047. X/* Kludge windows gets called by the routines that delete lines from the
  1048. X   buffer.  If the w->w_line or w->w_top are deleted and this procedure
  1049. X   is not called, the redisplay routine will barf. */
  1050. X
  1051. XChkWindows(line1, line2)
  1052. XLine    *line1;
  1053. Xregister Line    *line2;
  1054. X{
  1055. X    register Window    *w = fwind;
  1056. X    register Line    *lp;
  1057. X
  1058. X    do {
  1059. X        for (lp = line1->l_next; lp != line2->l_next; lp = lp->l_next) {
  1060. X            if (lp == w->w_top)
  1061. X                w->w_flags |= W_TOPGONE;
  1062. X            if (lp == w->w_line)
  1063. X                w->w_flags |= W_CURGONE;
  1064. X        }
  1065. X        w = w->w_next;
  1066. X    } while (w != fwind);
  1067. X}
  1068. X
  1069. Xextern int    RingBell;
  1070. X
  1071. Xredisplay()
  1072. X{
  1073. X    register Window    *w = fwind;
  1074. X    int    lineno,
  1075. X        done_ID = 0,
  1076. X        i;
  1077. X    register struct scrimage    *des_p,
  1078. X                    *phys_p;
  1079. X
  1080. X    curwind->w_line = curwind->w_bufp->b_dot;
  1081. X    curwind->w_char = curwind->w_bufp->b_char;
  1082. X
  1083. X    if (InputPending = charp())
  1084. X        return;
  1085. X
  1086. X#ifdef JOB_CONTROL
  1087. X    if (UpdFreq)
  1088. X        sighold(SIGALRM);
  1089. X#endif
  1090. X    if (RingBell) {
  1091. X        dobell(1);
  1092. X        RingBell = 0;
  1093. X    }
  1094. X    if (UpdMesg)
  1095. X        DrawMesg(YES);
  1096. X
  1097. X    for (lineno = 0, w = fwind; lineno < ILI; w = w->w_next) {
  1098. X        UpdWindow(w, lineno);
  1099. X        lineno += w->w_height;
  1100. X    }
  1101. X
  1102. X    des_p = DesiredScreen;
  1103. X    phys_p = PhysScreen;
  1104. X    for (i = 0; i < ILI; i++, des_p++, phys_p++) {
  1105. X        if (!done_ID && (des_p->s_id != phys_p->s_id)) {
  1106. X            DoIDline(i);
  1107. X            done_ID++;
  1108. X        }
  1109. X        if ((des_p->s_flags & (DIRTY | L_MOD)) ||
  1110. X            (des_p->s_id != phys_p->s_id) ||
  1111. X            (des_p->s_vln != phys_p->s_vln) ||
  1112. X            (des_p->s_offset != phys_p->s_offset))
  1113. X            UpdLine(i);
  1114. X        if (InputPending)
  1115. X            goto ret;
  1116. X    }
  1117. X
  1118. X    UpdModLine = 0;
  1119. X
  1120. X    if (Asking) {
  1121. X        Placur(LI - 1, min(CO - 2, calc_pos(mesgbuf, Asking)));
  1122. X            /* Nice kludge */
  1123. X        flusho();
  1124. X    } else
  1125. X        GotoDot();
  1126. Xret:
  1127. X#ifdef JOB_CONTROL
  1128. X    if (UpdFreq)
  1129. X        sigrelse(SIGALRM);
  1130. X#else
  1131. X    ;    /* yuck */
  1132. X#endif
  1133. X
  1134. X}
  1135. X
  1136. Xdobell(n)
  1137. X{
  1138. X    while (--n >= 0) {
  1139. X        if (VisBell && VB)
  1140. X            putstr(VB);
  1141. X        else
  1142. X#ifdef SYSV    /* release 2, at least */
  1143. X            putpad("$<20>\007", 1) ;
  1144. X#else
  1145. X            putpad("20\007", 1);
  1146. X#endif SYSV
  1147. X    }
  1148. X    flusho();
  1149. X}
  1150. X
  1151. X/* find_pos() returns the position on the line, that c_char represents
  1152. X   in line. */
  1153. X
  1154. Xfind_pos(line, c_char)
  1155. XLine    *line;
  1156. X{
  1157. X    return calc_pos(lcontents(line), c_char);
  1158. X}
  1159. X
  1160. Xcalc_pos(lp, c_char)
  1161. Xregister char    *lp;
  1162. Xregister int    c_char;
  1163. X{
  1164. X    register int    pos = 0;
  1165. X    register int    c;
  1166. X
  1167. X    while ((--c_char >= 0) && ((c = *lp++) & 0177) != 0) {
  1168. X        if (c == '\t')
  1169. X            pos += (tabstop - (pos % tabstop));
  1170. X        else if (isctrl(c))
  1171. X            pos += 2;
  1172. X        else
  1173. X            pos++;
  1174. X     }
  1175. X    return pos;
  1176. X}
  1177. X
  1178. Xint    UpdModLine = 0,
  1179. X    UpdMesg = 0,
  1180. X    CanScroll = 0;
  1181. X
  1182. XDoIDline(start)
  1183. X{
  1184. X    register struct scrimage    *des_p = &DesiredScreen[start];
  1185. X    struct scrimage    *phys_p = &PhysScreen[start];
  1186. X    register int    i,
  1187. X            j;
  1188. X
  1189. X    /* Some changes have been made.  Try for insert or delete lines.
  1190. X       If either case has happened, Addlines and/or DelLines will do
  1191. X       necessary scrolling, also CONVERTING PhysScreen to account for the
  1192. X       physical changes.  The comparison continues from where the
  1193. X       insertion/deletion takes place; this doesn't happen very often,
  1194. X       usually it happens with more than one window with the same
  1195. X       buffer. */
  1196. X
  1197. X    if (!CanScroll)
  1198. X        return;        /* We should never have been called! */
  1199. X
  1200. X    for (i = start; i < ILI; i++, des_p++, phys_p++)
  1201. X        if (des_p->s_id != phys_p->s_id)
  1202. X            break;
  1203. X
  1204. X    for (; i < ILI; i++) {
  1205. X        for (j = i + 1; j < ILI; j++) {
  1206. X            des_p = &DesiredScreen[j];
  1207. X            phys_p = &PhysScreen[j];
  1208. X            if (des_p->s_id != 0 && des_p->s_id == phys_p->s_id)
  1209. X                break;
  1210. X            if (des_p->s_id == PhysScreen[i].s_id) {
  1211. X                if (des_p->s_id == 0)
  1212. X                    continue;
  1213. X                if (AddLines(i, j - i)) {
  1214. X                    DoIDline(j);
  1215. X                    return;
  1216. X                }
  1217. X                break;
  1218. X            }
  1219. X            if ((des_p = &DesiredScreen[i])->s_id == phys_p->s_id) {
  1220. X                if (des_p->s_id == 0)
  1221. X                    continue;
  1222. X                if (DelLines(i, j - i)) {
  1223. X                    DoIDline(i);
  1224. X                    return;
  1225. X                }
  1226. X                break;
  1227. X            }
  1228. X        }
  1229. X    }
  1230. X}
  1231. X
  1232. X/* Make DesiredScreen reflect what the screen should look like when we are done
  1233. X   with the redisplay.  This deals with horizontal scrolling.  Also makes
  1234. X   sure the current line of the Window is in the window. */
  1235. X
  1236. XUpdWindow(w, start)
  1237. Xregister Window    *w;
  1238. X{
  1239. X    Line    *lp;
  1240. X    int    i,
  1241. X        DotIsHere = 0,
  1242. X        upper,        /* Top of window */
  1243. X        lower,        /* Bottom of window */
  1244. X        ntries = 0;    /* # of tries at updating window. */
  1245. X    register struct scrimage    *des_p,
  1246. X                    *phys_p;
  1247. X    Buffer    *bp = w->w_bufp;
  1248. X
  1249. Xretry:
  1250. X    if (w->w_flags & W_CURGONE) {
  1251. X        w->w_line = bp->b_dot;
  1252. X        w->w_char = bp->b_char;
  1253. X    }
  1254. X    if (w->w_flags & W_TOPGONE)
  1255. X        CentWind(w);    /* Reset topline of screen */
  1256. X    w->w_flags &= ~(W_CURGONE|W_TOPGONE);
  1257. X    for (i = w->w_height, lp = w->w_top; --i > 0 && lp != 0; lp = lp->l_next)
  1258. X        if (lp == w->w_line)
  1259. X            break;
  1260. X    if (i == 0 || lp == 0) {    /* current line not in window */
  1261. X        ntries++;
  1262. X        if (ntries == 1) {
  1263. X            CalcWind(w);
  1264. X            goto retry;
  1265. X        } else if (ntries == 2) {
  1266. X            w->w_top = w->w_line = w->w_bufp->b_first;
  1267. X            printf("\rERROR in redisplay: I got hopelessly lost!");
  1268. X            dobell(2);
  1269. X            goto retry;
  1270. X        } else if (ntries == 3) {
  1271. X            printf("\n\rOops, still lost, quitting ...\r\n");
  1272. X            finish(1);
  1273. X        }
  1274. X    }
  1275. X
  1276. X    upper = start;
  1277. X    lower = upper + w->w_height - 1;    /* Don't include modeline */
  1278. X    des_p = &DesiredScreen[upper];
  1279. X    phys_p = &PhysScreen[upper];
  1280. X    for (i = upper, lp = w->w_top; lp != 0 && i < lower; i++, des_p++, phys_p++, lp = lp->l_next) {
  1281. X        des_p->s_window = w;
  1282. X        des_p->s_lp = lp;
  1283. X        des_p->s_id = lp->l_dline & ~DIRTY;
  1284. X        des_p->s_flags = isdirty(lp) ? L_MOD : 0;
  1285. X        if (w->w_flags & W_NUMLINES)
  1286. X            des_p->s_vln = w->w_topnum + (i - upper);
  1287. X        else
  1288. X            des_p->s_vln = 0;
  1289. X
  1290. X        if (lp == w->w_line) {
  1291. X            int    diff = (w->w_flags & W_NUMLINES) ? 8 : 0,
  1292. X                strt_col = phys_p->s_offset,
  1293. X                end_col = strt_col + (CO - 2) - diff;
  1294. X
  1295. X            /* Right now we are displaying from strt_col to
  1296. X               end_col of the buffer line.  These are PRINT
  1297. X               colums, not actual characters. */
  1298. X            w->w_dotline = i;
  1299. X            w->w_dotcol = find_pos(lp, w->w_char);
  1300. X            /* if the new dotcol is out of range, reselect
  1301. X               a horizontal window */
  1302. X            if (w->w_dotcol < strt_col || w->w_dotcol >= end_col) {
  1303. X                if (w->w_dotcol < ((CO - 2) - diff))
  1304. X                    strt_col = 0;
  1305. X                else
  1306. X                    strt_col = w->w_dotcol - (CO / 2);
  1307. X            }
  1308. X            w->w_dotcol += diff;
  1309. X            des_p->s_offset = strt_col;
  1310. X            DotIsHere++;
  1311. X        } else
  1312. X            des_p->s_offset = 0;
  1313. X    }
  1314. X    if (!DotIsHere) {
  1315. X        f_mess("DotNotHere is impossible!");
  1316. X        finish(1);
  1317. X    }
  1318. X
  1319. X    /* Is structure assignment faster than copy each field seperately */
  1320. X    if (i < lower) {
  1321. X        static struct scrimage    dirty_plate = { 0, DIRTY, 0, 0, 0, 0 },
  1322. X                    clean_plate = { 0, 0, 0, 0, 0, 0 };
  1323. X
  1324. X        for (; i < lower; i++, des_p++, phys_p++)
  1325. X            if (phys_p->s_id != 0)
  1326. X                *des_p = dirty_plate;
  1327. X            else
  1328. X                *des_p = clean_plate;
  1329. X    }
  1330. X
  1331. X    des_p->s_window = w;
  1332. X    des_p->s_flags = 0;
  1333. X    if (((des_p->s_id = (int) w->w_bufp) != phys_p->s_id) || UpdModLine)
  1334. X        des_p->s_flags = MODELINE | DIRTY;
  1335. X}
  1336. X
  1337. X/* Write whatever is in mesgbuf (maybe we are Asking, or just printed
  1338. X   a message).  Turns off the UpdateMesg line flag. */
  1339. X
  1340. XDrawMesg(abortable)
  1341. X{
  1342. X    if (charp())
  1343. X        return;
  1344. X    i_set(ILI, 0);
  1345. X    if (swrite(mesgbuf, NIL, abortable)) {
  1346. X        cl_eol();
  1347. X        UpdMesg = 0;
  1348. X    }
  1349. X    flusho();
  1350. X}
  1351. X
  1352. X/* Goto the current position in the current window.  Presumably redisplay()
  1353. X   has already been called, and curwind->{w_dotline,w_dotcol} have been set
  1354. X   correctly. */
  1355. X
  1356. XGotoDot()
  1357. X{
  1358. X    if (InputPending)
  1359. X        return;
  1360. X    Placur(curwind->w_dotline, curwind->w_dotcol -
  1361. X                PhysScreen[curwind->w_dotline].s_offset);
  1362. X    flusho();
  1363. X}
  1364. X
  1365. Xprivate
  1366. XUntilEqual(start)
  1367. Xregister int    start;
  1368. X{
  1369. X    register struct scrimage    *des_p = &DesiredScreen[start],
  1370. X                    *phys_p = &PhysScreen[start];
  1371. X
  1372. X    while ((start < ILI) && (des_p->s_id != phys_p->s_id)) {
  1373. X        des_p++;
  1374. X        phys_p++;
  1375. X        start++;
  1376. X    }
  1377. X
  1378. X    return start;
  1379. X}
  1380. X
  1381. X/* Calls the routine to do the physical changes, and changes PhysScreen to
  1382. X   reflect those changes. */
  1383. X
  1384. XAddLines(at, num)
  1385. Xregister int    at,
  1386. X        num;
  1387. X{
  1388. X    register  int    i;
  1389. X    int    bottom = UntilEqual(at + num);
  1390. X
  1391. X    if (num == 0 || num >= ((bottom - 1) - at))
  1392. X        return 0;    /* We did nothing */
  1393. X    v_ins_line(num, at, bottom - 1);
  1394. X
  1395. X    /* Now change PhysScreen to account for the physical change. */
  1396. X
  1397. X    for (i = bottom - 1; i - num >= at; i--)
  1398. X        PhysScreen[i] = PhysScreen[i - num];
  1399. X    for (i = 0; i < num; i++)
  1400. X        PhysScreen[at + i].s_id = 0;
  1401. X    return 1;    /* We did something. */
  1402. X}
  1403. X
  1404. XDelLines(at, num)
  1405. Xregister int    at,
  1406. X        num;
  1407. X{
  1408. X    register int    i;
  1409. X    int    bottom = UntilEqual(at + num);
  1410. X
  1411. X    if (num == 0 || num >= ((bottom - 1) - at))
  1412. X        return 0;
  1413. X    v_del_line(num, at, bottom - 1);
  1414. X
  1415. X    for (i = at; num + i < bottom; i++)
  1416. X        PhysScreen[i] = PhysScreen[num + i];
  1417. X    for (i = bottom - num; i < bottom; i++)
  1418. X        PhysScreen[i].s_id = 0;
  1419. X    return 1;
  1420. X}
  1421. X
  1422. X/* Update line linenum in window w.  Only set PhysScreen to DesiredScreen
  1423. X   if the swrite or cl_eol works, that is nothing is interupted by 
  1424. X   characters typed. */ 
  1425. X
  1426. XUpdLine(linenum)
  1427. Xregister int    linenum;
  1428. X{
  1429. X    register struct scrimage    *des_p = &DesiredScreen[linenum];
  1430. X    register Window    *w = des_p->s_window;
  1431. X
  1432. X    i_set(linenum, 0);
  1433. X    if (des_p->s_flags & MODELINE)
  1434. X        ModeLine(w);
  1435. X    else if (des_p->s_id) {
  1436. X        des_p->s_lp->l_dline &= ~DIRTY;
  1437. X        des_p->s_flags &= ~(DIRTY | L_MOD);
  1438. X#ifdef ID_CHAR
  1439. X        if (!UseIC && (w->w_flags & W_NUMLINES))
  1440. X#else
  1441. X        if (w->w_flags & W_NUMLINES)
  1442. X#endif
  1443. X            (void) swrite(sprint("%6d  ", des_p->s_vln), NIL, YES);
  1444. X
  1445. X#ifdef ID_CHAR
  1446. X        if (UseIC) {
  1447. X            char    outbuf[256],
  1448. X                *lptr;
  1449. X            int    fromcol = (w->w_flags & W_NUMLINES) ? 8 : 0;
  1450. X
  1451. X            if (w->w_flags & W_NUMLINES)
  1452. X                sprintf(outbuf, "%6d  ", des_p->s_vln);
  1453. X            lptr = lcontents(des_p->s_lp);
  1454. X            DeTab(des_p->s_offset, lptr, outbuf + fromcol,
  1455. X                (sizeof outbuf) - 1 - fromcol,
  1456. X                des_p->s_window->w_flags & W_VISSPACE);
  1457. X            if (IDchar(outbuf, linenum, 0))
  1458. X                PhysScreen[linenum] = *des_p;
  1459. X            else if (i_set(linenum, 0), swrite(outbuf, NIL, YES))
  1460. X                do_cl_eol(linenum);
  1461. X            else
  1462. X                PhysScreen[linenum].s_id = -1;
  1463. X        } else
  1464. X#endif ID_CHAR
  1465. X            if (BufSwrite(linenum))
  1466. X            do_cl_eol(linenum);
  1467. X        else
  1468. X            PhysScreen[linenum].s_id = -1;
  1469. X    } else if (PhysScreen[linenum].s_id)    /* Not the same ... make sure */
  1470. X        do_cl_eol(linenum);
  1471. X}
  1472. X
  1473. Xdo_cl_eol(linenum)
  1474. Xregister int    linenum;
  1475. X{
  1476. X    cl_eol();
  1477. X    PhysScreen[linenum] = DesiredScreen[linenum];
  1478. X}
  1479. X
  1480. X#ifdef ID_CHAR
  1481. X
  1482. X/* From here to the end of the file is code that tries to utilize the
  1483. X   insert/delete character feature on some terminals.  It is very confusing
  1484. X   and not so well written code, AND there is a lot of it.  You may want
  1485. X   to use the space for something else. */
  1486. X
  1487. Xextern struct screenline    *Screen;
  1488. Xint    IN_INSmode = 0;
  1489. X
  1490. Xint    UseIC;
  1491. X
  1492. Xint    DClen,
  1493. X    MDClen,
  1494. X    IClen,
  1495. X    MIClen,
  1496. X    IMlen,
  1497. X    CElen;
  1498. X
  1499. Xdisp_opt_init()
  1500. X{
  1501. X    DClen = DC ? strlen(DC) : 0;
  1502. X    MDClen = M_DC ? strlen(M_DC) : 9999;
  1503. X    IClen = IC ? strlen(IC) : 0;
  1504. X    MIClen = M_IC ? strlen(M_IC) : 9999;
  1505. X    IMlen = IM ? strlen(IM) : 0;
  1506. X    CElen = CE ? strlen(CE) : 0;
  1507. X
  1508. X    UseIC = (IC || IM || M_IC);
  1509. X}
  1510. X
  1511. XINSmode(on)
  1512. X{
  1513. X    if (on && !IN_INSmode) {
  1514. X        putpad(IM, 1);
  1515. X        IN_INSmode++;
  1516. X    } else if (!on && IN_INSmode) {
  1517. X        putpad(EI, 1);
  1518. X        IN_INSmode = 0;
  1519. X    }
  1520. X}
  1521. X
  1522. Xprivate
  1523. XDeTab(s_offset, buf, outbuf, limit, visspace)
  1524. Xregister char    *buf;
  1525. Xchar    *outbuf;
  1526. X{
  1527. X    register char    *phys_p = outbuf,
  1528. X            c;
  1529. X    register int    pos = 0;
  1530. X    char        *limitp = &outbuf[limit];
  1531. X
  1532. X#define OkayOut(ch)    if ((pos++ >= s_offset) && (phys_p < limitp))\
  1533. X                *phys_p++ = ch;\
  1534. X            else
  1535. X
  1536. X    while (c = *buf++) {
  1537. X        if (c == '\t') {
  1538. X            int    nchars = (tabstop - (pos % tabstop));
  1539. X
  1540. X            if (visspace) {
  1541. X                OkayOut('>');
  1542. X                --nchars;
  1543. X            }
  1544. X            while (--nchars >= 0)
  1545. X                OkayOut(' ');
  1546. X
  1547. X        } else if (isctrl(c)) {
  1548. X            OkayOut('^');
  1549. X            OkayOut(c == 0177 ? '?' : c + '@');
  1550. X        } else {
  1551. X            if (visspace && c == ' ')
  1552. X                c = '_';
  1553. X            OkayOut(c);
  1554. X        }
  1555. X        if (pos - s_offset >= CO) {
  1556. X            phys_p = &outbuf[CO - 1];
  1557. X            *phys_p++ = '!';
  1558. X            break;
  1559. X        }            
  1560. X    }
  1561. X    *phys_p = 0;
  1562. X}
  1563. X
  1564. X/* ID character routines full of special cases and other fun stuff like that.
  1565. X   It actually works though ... 
  1566. X
  1567. X      Returns Non-Zero if you are finished (no differences left). */
  1568. X
  1569. Xprivate
  1570. XIDchar(new, lineno, col)
  1571. Xregister char    *new;
  1572. X{
  1573. X    register int    i;
  1574. X    int    j,
  1575. X        oldlen,
  1576. X        NumSaved;
  1577. X    register struct screenline    *sline = &Screen[lineno];
  1578. X
  1579. X    oldlen = sline->s_length - sline->s_line;
  1580. X
  1581. X    for (i = col; i < oldlen && new[i] != 0; i++)
  1582. X        if (sline->s_line[i] != new[i])
  1583. X            break;
  1584. X    if (new[i] == 0 || i == oldlen)
  1585. X        return (new[i] == 0 && i == oldlen);
  1586. X
  1587. X    for (j = i + 1; j < oldlen && new[j]; j++) {
  1588. X        if (new[j] == sline->s_line[i]) {
  1589. X            NumSaved = IDcomp(new + j, sline->s_line + i,
  1590. X                    strlen(new)) + NumSimilar(new + i,
  1591. X                        sline->s_line + i, j - i);
  1592. X            if (OkayInsert(NumSaved, j - i)) {
  1593. X                InsChar(lineno, i, j - i, new);
  1594. X                return(IDchar(new, lineno, j));
  1595. X            }
  1596. X        }
  1597. X    }
  1598. X
  1599. X    for (j = i + 1; j < oldlen && new[i]; j++) {
  1600. X        if (new[i] == sline->s_line[j]) {
  1601. X            NumSaved = IDcomp(new + i, sline->s_line + j,
  1602. X                    oldlen - j);
  1603. X            if (OkayDelete(NumSaved, j - i, new[oldlen] == 0)) {
  1604. X                DelChar(lineno, i, j - i);
  1605. X                return(IDchar(new, lineno, j));
  1606. X            }
  1607. X        }
  1608. X    }
  1609. X    return 0;
  1610. X}
  1611. X
  1612. Xprivate
  1613. XNumSimilar(s, t, n)
  1614. Xregister char    *s,
  1615. X        *t;
  1616. X{
  1617. X    register int    num = 0;
  1618. X
  1619. X    while (n--)
  1620. X        if (*s++ == *t++)
  1621. X            num++;
  1622. X    return num;
  1623. X}
  1624. X
  1625. Xprivate
  1626. XIDcomp(s, t, len)
  1627. Xregister char    *s,
  1628. X        *t;
  1629. X{
  1630. X    register int    i;
  1631. X    int    num = 0,
  1632. X        nonspace = 0;
  1633. X    char    c;
  1634. X
  1635. X    for (i = 0; i < len; i++) {
  1636. X        if ((c = *s++) != *t++)
  1637. X            break;
  1638. X        if (c != ' ')
  1639. X            nonspace++;
  1640. X        if (nonspace)
  1641. X            num++;
  1642. X    }
  1643. X
  1644. X    return num;
  1645. X}
  1646. X
  1647. Xprivate
  1648. XOkayDelete(Saved, num, samelength)
  1649. X{
  1650. X    /* If the old and the new are the same length, then we don't
  1651. X     * have to clear to end of line.  We take that into consideration.
  1652. X     */
  1653. X    return ((Saved + (!samelength ? CElen : 0))
  1654. X        > min(MDClen, DClen * num));
  1655. X}
  1656. X
  1657. Xprivate
  1658. XOkayInsert(Saved, num)
  1659. X{
  1660. X    register int    n = 0;
  1661. X
  1662. X    if (IC)        /* Per character prefixes */
  1663. X        n = min(num * IClen, MIClen);
  1664. X
  1665. X    if (IM && !IN_INSmode) {    
  1666. X        /* Good terminal.  Fewer characters in this case */
  1667. X        n += IMlen;
  1668. X    }
  1669. X
  1670. X    n += num;    /* The characters themselves */
  1671. X
  1672. X    return Saved > n;
  1673. X}
  1674. X
  1675. Xextern int    CapCol;
  1676. Xextern char    *cursend;
  1677. Xextern struct screenline    *Curline;
  1678. X
  1679. Xprivate
  1680. XDelChar(lineno, col, num)
  1681. X{
  1682. X    register char    *from,
  1683. X            *to;
  1684. X    register int    i;
  1685. X    struct screenline *sp = (&Screen[lineno]);
  1686. X
  1687. X    Placur(lineno, col);
  1688. X    if (M_DC && num > 1) {
  1689. X        char    minibuf[16];
  1690. X
  1691. X        sprintf(minibuf, M_DC, num);
  1692. X        putpad(minibuf, num);
  1693. X    } else {
  1694. X        for (i = num; --i >= 0; )
  1695. X            putpad(DC, 1);
  1696. X    }
  1697. X
  1698. X    to = sp->s_line + col;
  1699. X    from = to + num;
  1700. X
  1701. X    byte_copy(from, to, sp->s_length - from + 1);
  1702. X    clrline(sp->s_length - num, sp->s_length);
  1703. X    sp->s_length -= num;
  1704. X}
  1705. X
  1706. Xprivate
  1707. XInsChar(lineno, col, num, new)
  1708. Xchar    *new;
  1709. X{
  1710. X    register char    *sp1,
  1711. X            *sp2,    /* To push over the array. */
  1712. X            *sp3;    /* Last character to push over. */
  1713. X    int    i;
  1714. X
  1715. X    i_set(lineno, 0);
  1716. X    sp2 = Curline->s_length + num;
  1717. X
  1718. X    if (sp2 >= cursend) {
  1719. X        i_set(lineno, CO - num - 1);
  1720. X        cl_eol();
  1721. X        sp2 = cursend - 1;
  1722. X    }
  1723. X    Curline->s_length = sp2;
  1724. X    sp1 = sp2 - num;
  1725. X    sp3 = Curline->s_line + col;
  1726. X
  1727. X    while (sp1 >= sp3)
  1728. X        *sp2-- = *sp1--;
  1729. X
  1730. X    new += col;
  1731. X    byte_copy(new, sp3, num);
  1732. X    /* The internal screen is correct, and now we have to do
  1733. X       the physical stuff. */
  1734. X
  1735. X    Placur(lineno, col);
  1736. X    if (IM) {
  1737. X        if (!IN_INSmode)
  1738. X            INSmode(1);
  1739. X    } else if (M_IC && num > 1) {
  1740. X        char    minibuf[16];
  1741. X
  1742. X        sprintf(minibuf, M_IC, num);
  1743. X        putpad(minibuf, num);
  1744. X    } else if (IC) {
  1745. X        for (i = 0; i < num; i++)
  1746. X            putpad(IC, 1);
  1747. X    }
  1748. X    for (i = 0; i < num; i++) {
  1749. X        putchar(new[i]);
  1750. X        if (IN_INSmode)
  1751. X            putpad(IP, 1);
  1752. X    }
  1753. X    CapCol += num;
  1754. X}
  1755. X
  1756. X#endif ID_CHAR
  1757. X
  1758. X/* chkmail() returns nonzero if there is new mail since the
  1759. X   last time we checked. */
  1760. X
  1761. Xchar    Mailbox[128];    /* initialized in main */
  1762. Xint    MailInt = 60;    /* check no more often than 60 seconds */
  1763. X#ifdef BIFF
  1764. Xint    BiffChk = NO;    /* whether or not to turn off biff while in JOVE */
  1765. X#endif
  1766. X
  1767. Xchkmail(force)
  1768. X{
  1769. X    time_t    now;
  1770. X    static time_t    last_chk = 0;
  1771. X    static int    value = FALSE;
  1772. X    static off_t    last_size = 0;
  1773. X    struct stat    stbuf;
  1774. X    int    last_val;
  1775. X    extern time_t    time0;
  1776. X
  1777. X    time(&now);
  1778. X    if (!force && (now < last_chk + MailInt))
  1779. X        return value;
  1780. X    if (stat(Mailbox, &stbuf) < 0)
  1781. X        return FALSE;
  1782. X    last_val = value;
  1783. X    value = ((stbuf.st_mtime > time0) &&
  1784. X         (stbuf.st_size > 0) &&
  1785. X         (stbuf.st_size > last_size) &&
  1786. X         (stbuf.st_mtime + 5 > stbuf.st_atime));
  1787. X    last_chk = now;
  1788. X    last_size = stbuf.st_size;
  1789. X    if (value == TRUE && value != last_val)
  1790. X        dobell(3);
  1791. X    return value;
  1792. X}
  1793. X
  1794. X/* Print the mode line. */
  1795. X
  1796. Xprivate char    *mode_p,
  1797. X        *mend_p;
  1798. Xint    BriteMode = 1;        /* modeline should standout */
  1799. X
  1800. Xprivate
  1801. Xmode_app(str)
  1802. Xregister char    *str;
  1803. X{
  1804. X    if (mode_p >= mend_p)
  1805. X        return;
  1806. X    while ((mode_p < mend_p) && (*mode_p++ = *str++))
  1807. X        ;
  1808. X    mode_p--;    /* back over the null */
  1809. X}
  1810. X
  1811. Xchar    ModeFmt[120] = "%3c %[%sJOVE (%M)   Buffer: %b  \"%f\" %]%s%m*- %((%t)%s%)%e";
  1812. X
  1813. XModeLine(w)
  1814. Xregister Window    *w;
  1815. X{
  1816. X    extern int    i_line;
  1817. X    int    n,
  1818. X        ign_some = 0;
  1819. X    char    line[132],
  1820. X        *fmt = ModeFmt,
  1821. X        tmp[16],
  1822. X        fillc,
  1823. X        c;
  1824. X    register Buffer    *thisbuf = w->w_bufp;
  1825. X    register Buffer *bp;
  1826. X
  1827. X    mode_p = line;
  1828. X    mend_p = &line[(sizeof line) - 1];
  1829. X
  1830. X    if (BriteMode != 0 && SO == 0)
  1831. X        BriteMode = 0;
  1832. X    fillc = BriteMode ? ' ' : '-';
  1833. X
  1834. X    while (c = *fmt++) {
  1835. X        if (c != '%') {
  1836. X            if (c == '\\')
  1837. X                if ((c = *fmt++) == '\0')
  1838. X                    break;
  1839. X            if (!ign_some)
  1840. X                *mode_p++ = c;
  1841. X            continue;
  1842. X        }
  1843. X        if ((c = *fmt++) == '\0')    /* char after the '%' */
  1844. X            break;
  1845. X        if (ign_some && c != ')')
  1846. X            continue;
  1847. X        n = 1;
  1848. X        if (c >= '0' && c <= '9') {
  1849. X            n = 0;
  1850. X            while (c >= '0' && c <= '9') {
  1851. X                n = n * 10 + (c - '0');
  1852. X                c = *fmt++;
  1853. X            }
  1854. X        }
  1855. X        switch (c) {
  1856. X        case '(':
  1857. X            if (w->w_next != fwind)    /* Not bottom window. */
  1858. X                ign_some++;
  1859. X            break;
  1860. X
  1861. X        case ')':
  1862. X            ign_some = 0;
  1863. X            break;
  1864. X
  1865. X        case 'c':
  1866. X            while (--n >= 0)
  1867. X                *mode_p++ = fillc;
  1868. X            break;
  1869. X
  1870. X        case '[':
  1871. X        case ']':
  1872. X            {
  1873. X                char    *strs = (c == '[') ? "[[[[[[[[[[" : "]]]]]]]]]]";
  1874. X
  1875. X                mode_app(strs + 10 - RecDepth);
  1876. X            break;
  1877. X            }
  1878. X            
  1879. X        case 's':
  1880. X            if (mode_p[-1] == ' ')
  1881. X                continue;
  1882. X            *mode_p++ = ' ';
  1883. X            break;
  1884. X
  1885. X        case 'M':
  1886. X            {
  1887. X                static char    *mmodes[] = {
  1888. X                "Fundamental ",
  1889. X                "Text ",
  1890. X                "C ",
  1891. X#ifdef LISP
  1892. X                "Lisp ",
  1893. X#endif
  1894. X                0
  1895. X            };
  1896. X
  1897. X                mode_app(mmodes[thisbuf->b_major]);
  1898. X
  1899. X            if (BufMinorMode(thisbuf, Fill))
  1900. X                mode_app("Fill ");
  1901. X            if (BufMinorMode(thisbuf, Abbrev))
  1902. X                mode_app("Abbrev ");
  1903. X            if (BufMinorMode(thisbuf, OverWrite))
  1904. X                mode_app("OvrWt ");
  1905. X            if (BufMinorMode(thisbuf, Indent))
  1906. X                mode_app("AI ");
  1907. X            if (KeyMacro.m_flags & DEFINE)
  1908. X                mode_app("Def ");
  1909. X            mode_p--;    /* Back over the extra space. */
  1910. X            break;
  1911. X            }
  1912. X
  1913. X        case 'b':
  1914. X            mode_app(thisbuf->b_name);
  1915. X            break;
  1916. X
  1917. X        case 'f':
  1918. X        case 'F':
  1919. X            if (thisbuf->b_fname == 0)
  1920. X                mode_app("[No file]");
  1921. X            else {
  1922. X                if (c == 'f')
  1923. X                    mode_app(pr_name(thisbuf->b_fname));
  1924. X                else
  1925. X                    mode_app(basename(thisbuf->b_fname));
  1926. X            }
  1927. X            break;
  1928. X
  1929. X
  1930. X        case 'n':
  1931. X            for (bp = world, n = 1; bp != 0; bp = bp->b_next, n++)
  1932. X                if (bp == thisbuf)
  1933. X                    break;
  1934. X
  1935. X            sprintf(tmp, "%d", n);
  1936. X            mode_app(tmp);
  1937. X            break;
  1938. X
  1939. X        case 'm':
  1940. X            if (IsModified(w->w_bufp))
  1941. X                *mode_p++ = fmt[0];
  1942. X            else
  1943. X                *mode_p++ = fmt[1];
  1944. X            fmt += 2;    /* skip two characters */
  1945. X            break;
  1946. X
  1947. X        case 't':
  1948. X            {
  1949. X            char    timestr[12];
  1950. X
  1951. X                mode_app(get_time((time_t *) 0, timestr, 11, 16));
  1952. X            break;
  1953. X            }
  1954. X
  1955. X#ifdef LOAD_AV
  1956. X        case 'l':
  1957. X            {
  1958. X            double    theavg;
  1959. X                char    minibuf[10];
  1960. X
  1961. X                get_la(&theavg);
  1962. X                theavg += .005;    /* round to nearest .01 */
  1963. X                sprintf(minibuf, "%d.%02d",
  1964. X                   (int) theavg,
  1965. X                   (int)((theavg - (int) theavg) * 100));
  1966. X                mode_app(minibuf);
  1967. X            }
  1968. X            break;
  1969. X#endif
  1970. X
  1971. X        case 'C':    /* check mail here */
  1972. X            if (chkmail(NO))
  1973. X                mode_app("[New mail]");
  1974. X            break;
  1975. X
  1976. X#ifdef CHDIR
  1977. X        case 'd':    /* print working directory */
  1978. X            mode_app(pr_name(pwd()));
  1979. X            break;
  1980. X#endif
  1981. X            
  1982. X        case 'e':
  1983. X            {
  1984. X            /* 2 space pad pluss padding for magic cookies */
  1985. X            char    *last_p = &line[CO - 2 - (2 * SG)];
  1986. X
  1987. X            while (mode_p < last_p)
  1988. X                *mode_p++ = fillc;
  1989. X
  1990. X                goto outahere;        /* %e means we're done! */
  1991. X            }
  1992. X        }
  1993. X    }
  1994. X
  1995. Xoutahere:
  1996. X    *mode_p = 0;
  1997. X
  1998. X    /* Highlight mode line. */
  1999. X    if (BriteMode) {
  2000. X#ifdef ID_CHAR
  2001. X        if (IN_INSmode)
  2002. X            INSmode(0);
  2003. X#endif
  2004. X        putpad(SO, 1);
  2005. X    }
  2006. X    if (swrite(line, BriteMode, YES))
  2007. X        do_cl_eol(i_line);
  2008. X    if (BriteMode)
  2009. X        putpad(SE, 1);
  2010. X}
  2011. X
  2012. XRedrawDisplay()
  2013. X{
  2014. X    Line    *newtop = prev_line((curwind->w_line = curline), exp_p ?
  2015. X                exp : HALF(curwind));
  2016. X
  2017. X    if (newtop == curwind->w_top)
  2018. X        v_clear(FLine(curwind), FLine(curwind) + SIZE(curwind));
  2019. X    else
  2020. X        SetTop(curwind, newtop);
  2021. X}
  2022. X
  2023. Xv_clear(line1, line2)
  2024. Xregister int    line1;
  2025. X{
  2026. X    register struct scrimage    *phys_p, *des_p;
  2027. X
  2028. X    phys_p = &PhysScreen[line1];
  2029. X    des_p = &DesiredScreen[line1];
  2030. X
  2031. X    while (line1 <= line2) {
  2032. X        i_set(line1++, 0);
  2033. X        cl_eol();
  2034. X        phys_p->s_id = des_p->s_id = 0;
  2035. X        phys_p++, des_p++;
  2036. X    }
  2037. X}
  2038. X
  2039. XClAndRedraw()
  2040. X{
  2041. X    cl_scr(1);
  2042. X}
  2043. X
  2044. XNextPage()
  2045. X{
  2046. X    Line    *newline;
  2047. X
  2048. X    if (Asking)
  2049. X        return;
  2050. X    if (exp < 0) {
  2051. X        exp = -exp;
  2052. X        PrevPage();
  2053. X        return;
  2054. X    }
  2055. X    if (exp_p == YES)
  2056. X        UpScroll();
  2057. X    else {
  2058. X        if (in_window(curwind, curwind->w_bufp->b_last) != -1) {
  2059. X            rbell();
  2060. X            return;
  2061. X        }
  2062. X        newline = next_line(curwind->w_top, max(1, SIZE(curwind) - 1));
  2063. X        SetTop(curwind, curwind->w_line = newline);
  2064. X        if (curwind->w_bufp == curbuf)
  2065. X            SetLine(newline);
  2066. X    }
  2067. X}
  2068. X
  2069. XPrevPage()
  2070. X{
  2071. X    Line    *newline;
  2072. X
  2073. X    if (Asking)
  2074. X        return;
  2075. X    if (exp < 0) {
  2076. X        exp = -exp;
  2077. X        NextPage();
  2078. X        return;
  2079. X    }
  2080. X    if (exp_p == YES)
  2081. X        DownScroll();
  2082. X    else {
  2083. X        newline = prev_line(curwind->w_top, max(1, SIZE(curwind) - 1));
  2084. X        SetTop(curwind, curwind->w_line = newline);
  2085. X        if (curwind->w_bufp == curbuf)
  2086. X            SetLine(newline);
  2087. X    }
  2088. X}
  2089. X
  2090. XUpScroll()
  2091. X{
  2092. X    SetTop(curwind, next_line(curwind->w_top, exp));
  2093. X    if ((curwind->w_bufp == curbuf) &&
  2094. X        (in_window(curwind, curline) == -1))
  2095. X        SetLine(curwind->w_top);
  2096. X}
  2097. X
  2098. XDownScroll()
  2099. X{
  2100. X    SetTop(curwind, prev_line(curwind->w_top, exp));
  2101. X    if ((curwind->w_bufp == curbuf) &&
  2102. X        (in_window(curwind, curline) == -1))
  2103. X        SetLine(curwind->w_top);
  2104. X}
  2105. X
  2106. Xint    VisBell = 0,
  2107. X    RingBell = 0;    /* So if we have a lot of errors ...
  2108. X               ring the bell only ONCE */
  2109. Xrbell()
  2110. X{
  2111. X    RingBell++;
  2112. X}
  2113. X
  2114. X/* Message prints the null terminated string onto the bottom line of the
  2115. X   terminal. */
  2116. X
  2117. Xmessage(str)
  2118. Xchar    *str;
  2119. X{
  2120. X    if (InJoverc)
  2121. X        return;
  2122. X    UpdMesg++;
  2123. X    errormsg = 0;
  2124. X    if (str != mesgbuf)
  2125. X        null_ncpy(mesgbuf, str, (sizeof mesgbuf) - 1);
  2126. X}
  2127. X
  2128. X/* End of Window */
  2129. X
  2130. XEow()
  2131. X{
  2132. X    if (Asking)
  2133. X        return;
  2134. X    SetLine(next_line(curwind->w_top, SIZE(curwind) - 1 -
  2135. X            min(SIZE(curwind) - 1, exp - 1)));
  2136. X    if (exp_p == NO)
  2137. X        Eol();
  2138. X}
  2139. X
  2140. X/* Beginning of Window */
  2141. X
  2142. XBow()
  2143. X{
  2144. X    if (Asking)
  2145. X        return;
  2146. X    SetLine(next_line(curwind->w_top, min(SIZE(curwind) - 1, exp - 1)));
  2147. X}
  2148. X
  2149. Xprivate int    LineNo,
  2150. X        last_col,
  2151. X        DoAutoNL;
  2152. Xprivate Window    *old_wind;    /* save the window we were in BEFORE
  2153. X                   before we were called, if UseBuffers
  2154. X                   is nonzero */
  2155. X
  2156. Xint    UseBuffers = FALSE;
  2157. Xint    TOabort = 0;
  2158. X
  2159. X/* This initializes the typeout.  If send-typeout-to-buffers is set
  2160. X   the buffer NAME is created (emptied if it already exists) and output
  2161. X   goes to the buffer.  Otherwise output is drawn on the screen and
  2162. X   erased by TOstop() */
  2163. X
  2164. XTOstart(name, auto_newline)
  2165. Xchar    *name;
  2166. X{
  2167. X    if (UseBuffers) {
  2168. X        old_wind = curwind;
  2169. X        pop_wind(name, YES, B_SCRATCH);
  2170. X    }
  2171. X    TOabort = LineNo = last_col = 0;
  2172. X    DoAutoNL = auto_newline;
  2173. X}
  2174. X
  2175. X/* VARARGS1 */
  2176. X
  2177. XTypeout(fmt, va_alist)
  2178. Xchar    *fmt;
  2179. Xva_dcl
  2180. X{
  2181. X    if (TOabort)
  2182. X        return;
  2183. X
  2184. X    if (!UseBuffers && (LineNo == ILI - 1)) {
  2185. X        register int    c;
  2186. X
  2187. X        LineNo = 0;
  2188. X        last_col = 0;
  2189. X        f_mess("--more--");
  2190. X        if ((c = getchar()) != ' ') {
  2191. X            TOabort++;
  2192. X            if (c != CTL(G) && c != RUBOUT)
  2193. X                Ungetc(c);
  2194. X            return;
  2195. X        }
  2196. X        f_mess(NullStr);
  2197. X    }
  2198. X
  2199. X    if (fmt) {
  2200. X        extern int    i_col;
  2201. X        char    string[132];
  2202. X        va_list    ap;
  2203. X
  2204. X        va_start(ap);
  2205. X        format(string, sizeof string, fmt, ap);
  2206. X        va_end(ap);
  2207. X        if (UseBuffers)
  2208. X            ins_str(string, NO);
  2209. X        else {
  2210. X            i_set(LineNo, last_col);
  2211. X            (void) swrite(string, NIL, YES);
  2212. X            last_col = i_col;
  2213. X        }
  2214. X    }
  2215. X    if (!UseBuffers) {
  2216. X        PhysScreen[LineNo].s_id = -1;
  2217. X        if (fmt == 0 || DoAutoNL != 0) {
  2218. X            cl_eol();
  2219. X            flusho();
  2220. X            LineNo++;
  2221. X            last_col = 0;
  2222. X        }
  2223. X    } else if (fmt == 0 || DoAutoNL != 0)
  2224. X        ins_str("\n", NO);
  2225. X}
  2226. X
  2227. XTOstop()
  2228. X{
  2229. X    int    c;
  2230. X
  2231. X    if (UseBuffers) {
  2232. X        ToFirst();
  2233. X        SetWind(old_wind);
  2234. X    } else {
  2235. X        if (TOabort)
  2236. X            return;
  2237. X        if (last_col != 0)
  2238. X            Typeout((char *) 0);
  2239. X        Typeout("----------");
  2240. X        cl_eol();
  2241. X        flusho();
  2242. X        c = getchar();
  2243. X        if (c != ' ')
  2244. X            Ungetc(c);
  2245. X    }
  2246. X}
  2247. @//E*O*F disp.c//
  2248. if test 24166 -ne "`wc -c <'disp.c'`"; then
  2249.     echo shar: error transmitting "'disp.c'" '(should have been 24166 characters)'
  2250. fi
  2251. fi # end of overwriting check
  2252. echo shar: extracting "'fmt.c'" '(4845 characters)'
  2253. if test -f 'fmt.c' ; then 
  2254.   echo shar: will not over-write existing file "'fmt.c'"
  2255. else
  2256. sed 's/^X//' >fmt.c <<'@//E*O*F fmt.c//'
  2257. X/************************************************************************
  2258. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  2259. X * provided to you without charge, and with no warranty.  You may give  *
  2260. X * away copies of JOVE, including sources, provided that this notice is *
  2261. X * included in all the files.                                           *
  2262. X ************************************************************************/
  2263. X
  2264. X#include "jove.h"
  2265. X#include "io.h"
  2266. X#include "termcap.h"
  2267. X
  2268. X#include <varargs.h>
  2269. X
  2270. Xchar    mesgbuf[MESG_SIZE];
  2271. X
  2272. X/* VARARGS2 */
  2273. X
  2274. Xformat(buf, len, fmt, ap)
  2275. Xchar    *buf,
  2276. X    *fmt;
  2277. Xva_list    ap;
  2278. X{
  2279. X    File    strbuf,
  2280. X        *sp = &strbuf;
  2281. X
  2282. X     sp->f_ptr = sp->f_base = buf;
  2283. X    sp->f_fd = -1;        /* Not legit for files */
  2284. X    sp->f_cnt = len;
  2285. X    sp->f_flags = F_STRING;
  2286. X    sp->f_bufsize = len;
  2287. X
  2288. X    doformat(sp, fmt, ap);
  2289. X    putc('\0', sp);
  2290. X}
  2291. X
  2292. Xstatic char    padc = ' ';
  2293. Xstatic File    *curiop = 0;
  2294. X
  2295. Xstatic
  2296. XPPchar(c, str)
  2297. Xint    c;
  2298. Xchar    *str;
  2299. X{
  2300. X    char    *cp = str;
  2301. X
  2302. X    if (c == '\033')
  2303. X        strcpy(cp, "ESC");
  2304. X    else if (c < ' ')
  2305. X        sprintf(cp, "C-%c", c + '@');
  2306. X    else if (c == '\177')
  2307. X        strcpy(cp, "^?");
  2308. X    else
  2309. X        sprintf(cp, "%c", c);
  2310. X}
  2311. X
  2312. Xstatic
  2313. Xputld(leftadj, width, d, base)
  2314. Xlong    d;
  2315. X{
  2316. X    int    length = 1;
  2317. X    long    tmpd = d;
  2318. X
  2319. X    while (tmpd = (tmpd / base))
  2320. X        length++;
  2321. X    if (d < 0)
  2322. X        length++;
  2323. X    if (!leftadj)
  2324. X        pad(padc, width - length);
  2325. X    if (d < 0) {
  2326. X        putc('-', curiop);
  2327. X        d = -d;
  2328. X    }
  2329. X    outld(d, base);
  2330. X    if (leftadj)
  2331. X        pad(padc, width - length);
  2332. X}
  2333. X
  2334. Xstatic
  2335. Xoutld(d, base)
  2336. Xlong    d;
  2337. X{
  2338. X    long    n;
  2339. X
  2340. X    if (n = (d / base))
  2341. X        outld(n, base);
  2342. X    putc((int) ('0' + (int) (d % base)), curiop);
  2343. X}
  2344. X
  2345. Xstatic
  2346. Xputs(leftadj, width, str)
  2347. Xchar    *str;
  2348. X{
  2349. X    int    length;
  2350. X    register char    *cp,
  2351. X            c;
  2352. X
  2353. X    if (str == 0)
  2354. X#if pyr
  2355. X        str = "";
  2356. X#else
  2357. X        str = "(null)";
  2358. X#endif
  2359. X    length = strlen(str);
  2360. X    cp = str;
  2361. X    if (!leftadj)
  2362. X        pad(' ', width - length);
  2363. X    while (c = *cp++)
  2364. X        putc(c, curiop);
  2365. X    if (leftadj)
  2366. X        pad(' ', width - length);
  2367. X}
  2368. X
  2369. Xstatic
  2370. Xpad(c, amount)
  2371. Xregister int    c,
  2372. X        amount;
  2373. X{
  2374. X    while (--amount >= 0)
  2375. X        putc(c, curiop);
  2376. X}
  2377. X
  2378. Xstatic
  2379. Xdoformat(sp, fmt, ap)
  2380. Xregister File    *sp;
  2381. Xregister char    *fmt;
  2382. Xva_list    ap;
  2383. X{
  2384. X    register char    c;
  2385. X    int    leftadj,
  2386. X        width;
  2387. X    File    *pushiop = curiop;
  2388. X
  2389. X    curiop = sp;
  2390. X
  2391. X    while (c = *fmt++) {
  2392. X        if (c != '%') {
  2393. X            putc(c, sp);
  2394. X            continue;
  2395. X        }
  2396. X
  2397. X        padc = ' ';
  2398. X        leftadj = width = 0;
  2399. X        c = *fmt++;
  2400. X        if (c == '-') {
  2401. X            leftadj++;
  2402. X            c = *fmt++;
  2403. X        }
  2404. X        if (c == '0') {
  2405. X            padc = '0';
  2406. X            c = *fmt++;
  2407. X        }
  2408. X        while (c >= '0' && c <= '9') {
  2409. X            width = width * 10 + (c - '0');
  2410. X            c = *fmt++;
  2411. X        }
  2412. X        if (c == '*') {
  2413. X            width = va_arg(ap, int);
  2414. X            c = *fmt++;
  2415. X        }
  2416. X    reswitch:
  2417. X        /* At this point, fmt points at one past the format letter. */
  2418. X        switch (c) {
  2419. X        case '%':
  2420. X            putc('%', curiop);
  2421. X            break;
  2422. X    
  2423. X        case 'D':
  2424. X            putld(leftadj, width, va_arg(ap, long), 10);
  2425. X            break;
  2426. X    
  2427. X        case 'b':
  2428. X            {
  2429. X            Buffer    *b = va_arg(ap, Buffer *);
  2430. X
  2431. X            puts(leftadj, width, b->b_name);
  2432. X            break;
  2433. X            }
  2434. X
  2435. X        case 'c':
  2436. X            putc(va_arg(ap, int), curiop);
  2437. X            break;
  2438. X    
  2439. X        case 'd':
  2440. X            putld(leftadj, width, (long) va_arg(ap, int), 10);
  2441. X            break;
  2442. X    
  2443. X        case 'f':    /* current command name gets inserted here! */
  2444. X            puts(leftadj, width, LastCmd->Name);
  2445. X            break;
  2446. X
  2447. X        case 'l':
  2448. X            c = Upper(*++fmt);
  2449. X            goto reswitch;
  2450. X    
  2451. X        case 'n':
  2452. X            if (va_arg(ap, int) != 1)
  2453. X                puts(leftadj, width, "s");
  2454. X            break;
  2455. X
  2456. X        case 'o':
  2457. X            putld(leftadj, width, (long) va_arg(ap, int), 8);
  2458. X            break;
  2459. X    
  2460. X        case 'p':
  2461. X            {
  2462. X                char    cbuf[20];
  2463. X
  2464. X                PPchar(va_arg(ap, int), cbuf);
  2465. X                puts(leftadj, width, cbuf);
  2466. X                break;
  2467. X            }
  2468. X
  2469. X        case 's':
  2470. X            puts(leftadj, width, va_arg(ap, char *));
  2471. X            break;
  2472. X        
  2473. X        default:
  2474. X            complain("Unknown format directive: \"%%%c\"", c);
  2475. X        }
  2476. X    }
  2477. X    curiop = pushiop;
  2478. X}
  2479. X
  2480. X/* VARARGS1 */
  2481. X
  2482. Xchar *
  2483. Xsprint(fmt, va_alist)
  2484. Xchar    *fmt;
  2485. Xva_dcl
  2486. X{
  2487. X    va_list    ap;
  2488. X    static char    line[100];
  2489. X
  2490. X    va_start(ap);
  2491. X    format(line, sizeof line, fmt, ap);
  2492. X    va_end(ap);
  2493. X    return line;
  2494. X}
  2495. X
  2496. X/* VARARGS1 */
  2497. X
  2498. Xprintf(fmt, va_alist)
  2499. Xchar    *fmt;
  2500. Xva_dcl
  2501. X{
  2502. X    va_list    ap;
  2503. X
  2504. X    va_start(ap);
  2505. X    doformat(stdout, fmt, ap);
  2506. X    va_end(ap);
  2507. X}
  2508. X
  2509. X/* VARARGS1 */
  2510. X
  2511. Xfprintf(fp, fmt, va_alist)
  2512. XFile    *fp;
  2513. Xchar    *fmt;
  2514. Xva_dcl
  2515. X{
  2516. X    va_list    ap;
  2517. X
  2518. X    va_start(ap);
  2519. X    doformat(fp, fmt, ap);
  2520. X    va_end(ap);
  2521. X}
  2522. X
  2523. X/* VARARGS2 */
  2524. X
  2525. Xsprintf(str, fmt, va_alist)
  2526. Xchar    *str,
  2527. X    *fmt;
  2528. Xva_dcl
  2529. X{
  2530. X    va_list    ap;
  2531. X
  2532. X    va_start(ap);
  2533. X    format(str, 130, fmt, ap);
  2534. X    va_end(ap);
  2535. X}
  2536. X
  2537. X/* VARARGS1 */
  2538. X
  2539. Xs_mess(fmt, va_alist)
  2540. Xchar    *fmt;
  2541. Xva_dcl
  2542. X{
  2543. X    va_list    ap;
  2544. X
  2545. X    if (InJoverc)
  2546. X        return;
  2547. X    va_start(ap);
  2548. X    format(mesgbuf, sizeof mesgbuf, fmt, ap);
  2549. X    va_end(ap);
  2550. X    message(mesgbuf);
  2551. X}
  2552. X
  2553. X/* VARARGS1 */
  2554. X
  2555. Xf_mess(fmt, va_alist)
  2556. Xchar    *fmt;
  2557. Xva_dcl
  2558. X{
  2559. X    va_list    ap;
  2560. X
  2561. X    va_start(ap);
  2562. X    format(mesgbuf, sizeof mesgbuf, fmt, ap);
  2563. X    va_end(ap);
  2564. X    DrawMesg(NO);
  2565. X    UpdMesg++;    /* Still needs updating (for convenience) */
  2566. X}
  2567. X
  2568. X/* VARARGS1 */
  2569. X
  2570. Xadd_mess(fmt, va_alist)
  2571. Xchar    *fmt;
  2572. Xva_dcl
  2573. X{
  2574. X    int    mesg_len = strlen(mesgbuf);
  2575. X    va_list    ap;
  2576. X
  2577. X    if (InJoverc)
  2578. X        return;
  2579. X    va_start(ap);
  2580. X    format(&mesgbuf[mesg_len], (sizeof mesgbuf) - mesg_len, fmt, ap);
  2581. X    va_end(ap);
  2582. X    message(mesgbuf);
  2583. X}
  2584. @//E*O*F fmt.c//
  2585. if test 4845 -ne "`wc -c <'fmt.c'`"; then
  2586.     echo shar: error transmitting "'fmt.c'" '(should have been 4845 characters)'
  2587. fi
  2588. fi # end of overwriting check
  2589. echo shar: extracting "'re.h'" '(856 characters)'
  2590. if test -f 're.h' ; then 
  2591.   echo shar: will not over-write existing file "'re.h'"
  2592. else
  2593. sed 's/^X//' >re.h <<'@//E*O*F re.h//'
  2594. X/************************************************************************
  2595. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  2596. X * provided to you without charge, and with no warranty.  You may give  *
  2597. X * away copies of JOVE, including sources, provided that this notice is *
  2598. X * included in all the files.                                           *
  2599. X ************************************************************************/
  2600. X
  2601. X#define NALTS    10    /* number of alternate search strings */
  2602. X
  2603. Xextern char    searchstr[128],
  2604. X        compbuf[128],        /* global default compbuf */
  2605. X        rep_search[128],    /* replace search string */
  2606. X        rep_str[128],        /* contains replacement string */
  2607. X        *cur_compb,        /* usually points at compbuf */
  2608. X        REbuf[LBSIZE],        /* points at line we're scanning */
  2609. X        *alternates[NALTS];
  2610. X
  2611. Xextern int    REdirection,
  2612. X        REeom,
  2613. X        REbom,
  2614. X        REalt_num;
  2615. @//E*O*F re.h//
  2616. if test 856 -ne "`wc -c <'re.h'`"; then
  2617.     echo shar: error transmitting "'re.h'" '(should have been 856 characters)'
  2618. fi
  2619. fi # end of overwriting check
  2620. echo shar: extracting "'rec.h'" '(699 characters)'
  2621. if test -f 'rec.h' ; then 
  2622.   echo shar: will not over-write existing file "'rec.h'"
  2623. else
  2624. sed 's/^X//' >rec.h <<'@//E*O*F rec.h//'
  2625. X/************************************************************************
  2626. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  2627. X * provided to you without charge, and with no warranty.  You may give  *
  2628. X * away copies of JOVE, including sources, provided that this notice is *
  2629. X * included in all the files.                                           *
  2630. X ************************************************************************/
  2631. X
  2632. Xstruct rec_head {
  2633. X    int    Uid,        /* Uid of owner. */
  2634. X        Pid;        /* Pid of jove process. */
  2635. X    time_t    UpdTime;    /* Last time this was updated. */
  2636. X    int    Nbuffers;    /* Number of buffers. */
  2637. X};
  2638. X
  2639. Xstruct rec_entry {
  2640. X    char    r_bname[128],
  2641. X        r_fname[128];
  2642. X    int    r_nlines;
  2643. X};
  2644. X
  2645. @//E*O*F rec.h//
  2646. if test 699 -ne "`wc -c <'rec.h'`"; then
  2647.     echo shar: error transmitting "'rec.h'" '(should have been 699 characters)'
  2648. fi
  2649. fi # end of overwriting check
  2650. echo shar: extracting "'doc/cmds.doc.nr'" '(238 characters)'
  2651. if test -f 'doc/cmds.doc.nr' ; then 
  2652.   echo shar: will not over-write existing file "'doc/cmds.doc.nr'"
  2653. else
  2654. sed 's/^X//' >doc/cmds.doc.nr <<'@//E*O*F doc/cmds.doc.nr//'
  2655. X.de bp
  2656. X..
  2657. X.de NH
  2658. X..
  2659. X.de IQ
  2660. X"\\$1"
  2661. X..
  2662. X.de dc
  2663. X.sp 1
  2664. X:entry "\\$1"
  2665. X.if '\\$2'(variable)' "Variable"
  2666. X.if !'\\$2'(variable)' "Command"
  2667. X.br
  2668. X..
  2669. X.de ID
  2670. X.sp 1
  2671. X.in +5
  2672. X..
  2673. X.de DE
  2674. X.fi
  2675. X.sp 1
  2676. X.in -5
  2677. X..
  2678. X.de DS
  2679. X.nf
  2680. X.sp 1
  2681. X.in +5
  2682. X..
  2683. X.de UX
  2684. XUNIX\c
  2685. X..
  2686. X.ll 7i
  2687. @//E*O*F doc/cmds.doc.nr//
  2688. if test 238 -ne "`wc -c <'doc/cmds.doc.nr'`"; then
  2689.     echo shar: error transmitting "'doc/cmds.doc.nr'" '(should have been 238 characters)'
  2690. fi
  2691. fi # end of overwriting check
  2692. echo shar: "End of archive 2 (of 13)."
  2693. cp /dev/null ark2isdone
  2694. DONE=true
  2695. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
  2696.     if test -f ark${I}isdone; then
  2697.         echo "You have run archive ${I}."
  2698.     else
  2699.         echo "You still need to run archive ${I}."
  2700.         DONE=false
  2701.     fi
  2702. done
  2703. case $DONE in
  2704.     true)
  2705.         echo "You have run all 13 archives."
  2706.         echo 'Now read the README and Makefile.'
  2707.         ;;
  2708. esac
  2709. ##  End of shell archive.
  2710. exit 0
  2711.